#include <algorithm>
#include "2pdm_optimal_irreps.h"
#include "npdm_typedefs.h"

namespace Npdm {
//----------------------------------------------------------------------------------------------------------------------------------------------------------
// Constructor for 2PDM_index object.

TwoPdmBlueprint::TwoPdmBlueprint (int kmax) {

  std::vector< std::vector< std::tuple<int,CRE_DES > > > ij_vec, lm_vec;
  kmax_ = kmax;

  // Build creation 2-indices ordered by site
  get2opsPerms(ij_vec,CREATION);
  // Build destruction 2-indices ordered by site
  get2opsPerms(lm_vec,DESTRUCTION);

  buildIrrepOpStrings( ij_vec, lm_vec );
  buildDMRGmap();

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------
// Build ordered non-zero permutations of 3 creation/des ops.
// Sorted by site-index

void TwoPdmBlueprint::get2opsPerms(std::vector< std::vector< std::tuple<int,CRE_DES> > > & pq_vec, CRE_DES cre_des) {

  std::vector< std::tuple<int,CRE_DES> > ops(2, std::make_tuple(0,CREATION) );
  std::vector< std::tuple<int,CRE_DES> > tmp;

  for (int i=1; i<=kmax_ ; i++) {
    ops[0] = std::make_tuple(abs(i), cre_des);
    
    for (int j=i; j<=kmax_ ; j++) {
      if (j==0) continue;
      ops[1] = std::make_tuple(abs(j), cre_des);
      tmp = ops;
      std::sort( tmp.begin(), tmp.end() );
      pq_vec.push_back( tmp );

    }
  }

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------
}
